﻿using Newtonsoft.Json.Linq;
using PlayListSet.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using VCLib.Network.HTTPServers;

namespace PlayListSet.Comm
{
    public class InputControl
    {
        VCLib.Network.UDPServer UDPServer { get; set; }
        VCLib.Network.HTTPServers.WebHttpService httpService { get; set; }
        public InputControl()
        {
            UDPServer = new VCLib.Network.UDPServer(AppControl.Instance.AppConfig.UdpPort);
            UDPServer.SocketServerStateEvent += UDPServer_SocketServerStateEvent;
            UDPServer.DataReceivedEvent += UDPServer_DataReceivedEvent;

            var urls = VCLib.Network.HTTPServers.HttpServiceTool.GetHttpLocalUri(AppControl.Instance.AppConfig.ApiPort);
            httpService = new VCLib.Network.HTTPServers.WebHttpService(urls);
            httpService.CrossDomain = true;
            httpService.HttpServiceConnectionEvent += HttpService_HttpServiceConnectionEvent;
        }



        private byte[] UDPServer_DataReceivedEvent(object sender, VCLib.Network.Entity.SocketServerReceivedDataArg args)
        {
            try
            {
                var str = Encoding.UTF8.GetString(args.Data).Trim();
                var cmdArr = str.Split(';');
                for (int i = 0; i < cmdArr.Length; i++)
                {
                    try
                    {
                        if (string.IsNullOrEmpty(str))
                            continue;
                        HandleCMD(cmdArr[i]);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(str + "  " + ex.Message);
                    }
                }
                AppControl.Instance.Log("控制成功：" + str);
                return null;
            }
            catch (Exception ex)
            {
                AppControl.Instance.Log("控制失败：" + ex.Message);
                return null;
            }

        }
        public void HandleCMD(UserPlayInfoCmd cmd)
        {
            AppControl.Instance.Log("HandleCMD：" + cmd.Name);
            var str = cmd.GetCmd();
            Console.WriteLine(str);
            var cmdArr = str.Split(';');
            for (int i = 0; i < cmdArr.Length; i++)
            {
                try
                {
                    if (string.IsNullOrEmpty(str))
                        continue;
                    HandleCMD(cmdArr[i]);
                }
                catch (Exception ex)
                {
                    throw new Exception(str + "  " + ex.Message);
                }
            }
        }

        public void HandleCMD(string str)
        {
            if (string.IsNullOrEmpty(str))
                throw new Exception("空指令");
            str = str.Trim();
            str = str.ToLower();
            if (str.StartsWith("play:"))
            {
                AppControl.Instance.TimeCodePlayContorl.Play();
            }
            else if (str.StartsWith("stop:"))
            {
                AppControl.Instance.TimeCodePlayContorl.Stop();
            }
            else if (str.StartsWith("pause:"))
            {
                AppControl.Instance.TimeCodePlayContorl.Pause();
            }
            else if (str.StartsWith("vol:"))
            {

                var volStr = str.Substring("vol:".Length);
                var vol = Convert.ToInt32(volStr);
                if (vol >= 0 && vol <= 100)
                {
                    AppControl.Instance.MainWindow.SetVol(vol);
                }
            }
            else if (str.StartsWith("seek:"))
            {
                var timeStr = str.Substring("seek:".Length);
                string[] ms = timeStr.Split('.');

                var timeArr = ms[0].Split(':');
                TimeSpan timeSpan = new TimeSpan(System.Convert.ToInt32(timeArr[0]), System.Convert.ToInt32(timeArr[1]), System.Convert.ToInt32(timeArr[2]));

                if (ms.Length == 2)
                {
                    var m = TimeSpan.FromSeconds(System.Convert.ToDouble("0."+ms[1]));

                    timeSpan = timeSpan.Add(m);
                }

                AppControl.Instance.TimeCodePlayContorl.Seek(timeSpan);

            }
            else
            {
                throw new Exception("未知指令");
            }
        }

        private void UDPServer_SocketServerStateEvent(object sender, VCLib.Network.SocketServerStateEventArg arg)
        {
            AppControl.Instance.Log("控制端口监听：" + arg.State);
        }

        public void Open()
        {
            UDPServer.Open();
            httpService.Open();
        }
        public void Close()
        {
            try
            {
                UDPServer.Close();
            }
            catch (Exception)
            {
            }
            try
            {
                httpService.Close();
            }
            catch (Exception)
            {

            }


        }

        private string HttpService_HttpServiceConnectionEvent(object sender, VCLib.Network.HTTPServers.HttpServiceConnectionArg arg)
        {
            var res = new Result();
            arg.Response.ContentType = HttpServiceConnectionArg.JSON;
            arg.SetResponseEncoding(Encoding.UTF8);
            try
            {
                arg.Response.StatusCode = 200;
                var rawUrl = arg.Request.Url.LocalPath;

                if (rawUrl == "/api/getState")
                {
                    res.State = 1;
                    res.Data = PlayState.GetPlayState();
                    return res.GetJson();
                }

                if (rawUrl == "/api/controlProgram")
                {
                    // 使用UrlDecode进行解码
                    string decodedString = WebUtility.UrlDecode(arg.Request.Url.Query);
                    var map = GetHttpGetArg(decodedString);
                    if (!map.ContainsKey("program"))
                    {
                        throw new Exception("参数错误");
                    }
                    var name = map["program"];
                    var cmds = AppControl.Instance.UserPlayInfoCmds;
                    try
                    {
                        foreach (var item in cmds)
                        {
                            if (string.Equals(item.Name, name, StringComparison.Ordinal))
                            {
                                HandleCMD(item);
                                res.State = 1;
                                res.Msg = "控制成功";
                                return res.GetJson();
                            }
                        }
                        throw new Exception("节目不存在");
                    }
                    catch (Exception ex)
                    {
                        res.State = 0;
                        res.Msg = ex.Message;
                        return res.GetJson();
                    }


                }
                if (rawUrl == "/api/controlProgramById")
                {
                    // 使用UrlDecode进行解码
                    string decodedString = WebUtility.UrlDecode(arg.Request.Url.Query);
                    var map = GetHttpGetArg(decodedString);
                    if (!map.ContainsKey("id"))
                    {
                        throw new Exception("参数错误");
                    }
                    var id = map["id"];
                    var cmds = AppControl.Instance.UserPlayInfoCmds;
                    try
                    {
                        foreach (var item in cmds)
                        {
                            if (string.Equals(item.ID, id, StringComparison.Ordinal))
                            {
                                HandleCMD(item);
                                res.State = 1;
                                res.Msg = "控制成功";
                                return res.GetJson();
                            }
                        }
                        throw new Exception("节目不存在");
                    }
                    catch (Exception ex)
                    {
                        res.State = 0;
                        res.Msg = ex.Message;
                        return res.GetJson();
                    }


                }
                else if (rawUrl == "/api/setVol")
                {
                    var vol = arg.GetArgValue("vol");
                    try
                    {
                        var d = Convert.ToInt32(vol);
                        if (d >= 0 && d <= 100)
                        {
                            AppControl.Instance.MainWindow.SetVol(d);
                        }
                        res.State = 1;
                        res.Msg = "控制成功";
                        return res.GetJson();
                    }
                    catch (Exception ex)
                    {
                        res.State = 0;
                        res.Msg = ex.Message;
                        return res.GetJson();
                    }
                }
                else if (rawUrl == "/api/cmd")
                {
                    var cmd = arg.GetArgValue("cmd");
                    try
                    {
                        HandleCMD(cmd);
                        res.State = 1;
                        res.Msg = "控制成功";
                        return res.GetJson();
                    }
                    catch (Exception ex)
                    {
                        res.State = 0;
                        res.Msg = ex.Message;
                        return res.GetJson();
                    }
                }

                arg.Response.StatusCode = 404;
                res.Msg = "没有指定资源";
                return res.GetJson();
            }
            catch (Exception ex)
            {
                res.State = 0;
                res.Msg = ex.Message;
                return res.GetJson();
            }

        }
        private Dictionary<string, string> GetHttpGetArg(string queString)
        {
            queString = queString.TrimStart('?').Trim();
            var arr = queString.Split('=');
            Dictionary<string, string> map = new Dictionary<string, string>();
            for (int i = 0; i < arr.Length; i += 2)
            {
                map.Add(arr[i], arr[i + 1]);
            }
            return map;
        }
    }
    public class programModle
    {
        public string ID { get; set; }
        public string Name { get; set; }
    }
    public class PlayState
    {
        public double CurrentTime { get; set; }
        public int CurrentState { get; set; }
        public int MainVol { get; set; }

        public List<programModle> ProgramList { get; set; }

        public static PlayState GetPlayState()
        {
            var a = AppControl.Instance.UserPlayInfoCmds;
            List<programModle> programList = new List<programModle>();
            foreach (var item in a)
            {
                programList.Add(new programModle() {  ID=item.ID,Name=item.Name} );
            }
            var playState = new PlayState()
            {
                CurrentTime = AppControl.Instance.TimeCodePlayContorl.GetCurrentTime().TotalSeconds,
                CurrentState = AppControl.Instance.TimeCodePlayContorl.PlaybackStateInt,
                MainVol = AppControl.Instance.AppConfig.Vol,
                ProgramList = programList
            };
            return playState;
        }

    }

    public class Result
    {
        public int State { get; set; }
        public object Data { get; set; }
        public string Msg { get; set; }
        public string GetJson()
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(this);
        }
    }
}
